package org.firebug.spring.boot.jackson.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.util.Assert;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * 金额转中文大写,如：100 -> 壹佰圆整
 * @Author: 张晓东
 */
public class AmountToUpperSerializer extends JsonSerializer<BigDecimal> {
    private static final String[] DIGIT = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
    private static final String[] UNIT1 = { "圆","拾","佰","仟","万","拾","佰","仟","亿","拾","佰","仟"};
    private static final String[] UNIT2 = { "角", "分", "厘", "毫"};
    private static final String UNIT3 = "整";

    private static String convertAmount(BigDecimal amount) {
        String[] sAmount = amount.toPlainString().split("\\.");
        String integer = convertInteger(sAmount[0]);
        if (sAmount.length == 1) {
            return integer + UNIT3;
        }
        String decimal = convertDecimal(sAmount[1]);
        return integer + decimal;
    }

    private static String convertInteger(String integer) {
        StringBuilder builder = new StringBuilder();
        int zeros = 0;
        char[] digits = integer.toCharArray();
        Assert.isTrue(digits.length <= UNIT1.length, "金额过大无法转换");
        for (int i = 0; i < digits.length; i++) {
            int unitIndex = digits.length - i - 1;
            int digitIndex = digits[i] - 0x30;
            if(digits[i] == '0') {
                zeros++;
                if(unitIndex % 4 == 0 && (zeros < 4 || unitIndex == 0)) {
                    // integer == 0,输出：零
                    if(digits.length == 1) {
                        builder.append(DIGIT[0]);
                    }
                    builder.append(UNIT1[unitIndex]); //亿万圆
                    zeros = 0;
                }
                continue;
            }
            if(zeros > 0) {
                builder.append(DIGIT[0]);
            }
            builder.append(DIGIT[digitIndex]).append(UNIT1[unitIndex]);
            zeros = 0;
        }
        return builder.toString();
    }

    private static String convertDecimal(String decimal) {
        StringBuilder builder = new StringBuilder();
        boolean zero = false;
        char[] digits = decimal.toCharArray();
        int length = Math.min(digits.length, UNIT2.length);
        for (int i = 0; i < length; i++) {
            if(digits[i] == '0') {
                zero = true;
                continue;
            }
            if(zero) {
                builder.append(DIGIT[0]);
                zero = false;
            }
            builder.append(DIGIT[digits[i] - 0x30]).append(UNIT2[i]);
        }
        return builder.toString();
    }

    @Override
    public void serialize(BigDecimal amount, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        String value = this.convertAmount(amount);
        gen.writeString(value);
    }
}
